#include "udpServer.hpp"
#include <memory>
#include <unordered_map>
#include<fstream>
#include<signal.h>
#include"OnlineUser.hpp"
using namespace std;
using namespace Server;
const std::string dictTxT = "./dict.txt";
// static void usage(std::string proc)
// {
//     std::cout << "\nUsage:\n\t" << proc << "local_ip local_port\n\t\n";
// }
static void usage(std::string proc)
{
    std::cout << "\nUsage:\n\t" << proc << " local_port\n\t\n";
}

// static bool cutString(const string& line,string* key,string* value,string& sep)
// {
//     auto pos = line.find(sep);
//     if(pos == std::string::npos)return false;
//     *key =  line.substr(0,pos);
//     *value = line.substr(pos+1);
//     return true;
// }

// unordered_map<string,string> dict;//可以写一个字典！
// static void iniDict()
// {
//     ifstream in(dictTxT,std::ios::binary);
//     if(!in.is_open())
//     {
//         std::cerr << "open file " << dictTxT << " error" << endl;
//         exit(OPEN_ERR);
//     }
//     string line;
//     string key, value;
//     string sep = ":";
//     while(getline(in,line))//从配置文件里面读取内容！
//     {
//         // cout << line <<endl;
//         if(cutString(line,&key,&value,sep))
//         {
//             dict.insert(make_pair(key,value));
//         }
//     }
//     cout << "load dict success ! " << endl;
// }

// static void debugPrint()//每写一个小模块都要测试一下！
// {
//     for(auto& dt:dict)
//     {
//         cout << dt.first << "#"<<dt.second << endl;
//     }
// }

// void reload(int signo)
// {
//     (void)signo;
//     iniDict();
// }


// void handlerMessage(int sockfd,string clientip,uint16_t clientport,string messages)
// {
//     //在这里就可以对Message进行特定的业务处理！而不用关心Message怎么来的！
//     //这就完成了Server通信和业务逻辑解耦！

//     //现在实现一个简单的翻译的业务！
//     string respons_meassge;
//     auto iter  = dict.find(messages);
//     if(iter == dict.end())respons_meassge = "unknonw";
//     else respons_meassge = iter->second;

//     //我们接下来就可以将消息发回去！
//     struct sockaddr_in peer;
//     bzero(&peer,sizeof(peer));//清0
//     peer.sin_family = AF_INET;
//     peer.sin_port = htons(clientport);
//     peer.sin_addr.s_addr = inet_addr(clientip.c_str());

//     sendto(sockfd,respons_meassge.c_str(),respons_meassge.size(),0,(struct sockaddr*)&peer,sizeof(peer));
// }




// void exceCommand(int sockfd,string clientip,uint16_t clientport,string cmd)
// {
//     //1.进行cmd的解析工作 例如：ls -a -l
//     //如果必要我们可能要进行fork
//     if(cmd.find("rm")!= string::npos || cmd.find("mv")!= string::npos || cmd.find("rmdir")!= string::npos)
//     {
//         cerr << clientip << ":" << clientport <<" 正在做一个非法的操作" << cmd << endl;
//         return;
//     }

//     string respons;
//     FILE* fp = popen(cmd.c_str(),"r"); 
//     if(fp == nullptr)respons = cmd + "exec fail";

//     char line[1024];
//     while(fgets(line,sizeof(line),fp))//使用fgets从文件获取数据！
//     {
//         respons +=line;
//     }
//     struct sockaddr_in peer;
//     bzero(&peer,sizeof(peer));//清0
//     peer.sin_family = AF_INET;
//     peer.sin_port = htons(clientport);
//     peer.sin_addr.s_addr = inet_addr(clientip.c_str());
//     sendto(sockfd,respons.c_str(),respons.size(),0,(struct sockaddr*)&peer,sizeof(peer));
//     pclose(fp);

// }
OnlineUser onlineuser;
void routeMessage(int sockfd,string clientip,uint16_t clientport,string messages)
{
    if(messages == "online") onlineuser.addUser(clientip,clientport);//加入到在线列表里面！
    //如果以后想要添加登录系统只要把这个if的判断行为改为注册/登录行为！

    if(messages == "offline") onlineuser.DelUser(clientip,clientport);
    if(onlineuser.isOnline(clientip,clientport))//判断用户是不是在线！如果是在线！那么就对信息进行转发！
    {
        //消息的路由
        //服务器收到了一条消息！——然后将这条消息sendto给所有的用户！这就完成了一次转发！
        onlineuser.broadcastMessage(sockfd,clientip,clientport,messages);

    }
    else //如果不在线，那么就单独的对其发送信息！
    {
        struct sockaddr_in peer;
        bzero(&peer, sizeof(peer)); // 清0
        peer.sin_family = AF_INET;
        peer.sin_port = htons(clientport);
        peer.sin_addr.s_addr = inet_addr(clientip.c_str());

        string respons = "you don't online! please sendto online to run!";
        sendto(sockfd, respons.c_str(), respons.size(), 0, (struct sockaddr *)&peer, sizeof(peer));
    }

}
int main(int argc,char* argv[])
{
    if(argc != 2)
    {
        usage(argv[0]);
        exit(USAGE_ERR);
    }
    // string ip = argv[1];
    uint16_t port = atoi(argv[1]);//将字符串转换为整数
    
    // iniDict();    
    // signal(2,reload);
    // debugPrint();
    // std::unique_ptr<udpServer> server(new udpServer(handlerMessage,port));
    // std::unique_ptr<udpServer> server(new udpServer(exceCommand,port));
    std::unique_ptr<udpServer> server(new udpServer(routeMessage,port));

    server->initServer();//初始化服务端
    server->start();//启动服务端

    return 0;
}